package uk.ac.strath.cis.religionsearch.model;

import java.io.File;

import java.util.ArrayList;
import java.util.Observable;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import uk.ac.strath.cis.religionsearch.model.indexer.Indexer;

public class Model extends Observable{
	
	private String index;  // Path that the index will be creatied in
	private String xmlFilePath; // Path to the files to be added to the index
	
	private String[] tstmtsResults; // Array of Testaments, e.g. All (762), New Testament (762)
	private String[] bookResults; // Array of books with corresponding hits
	private String[] chapterResults; 
	private ScoreDoc[] allDocs; 
	private Query currentQuery;
	                
	public Model(){
		index="/index";
		tstmtsResults = new String[0];
		bookResults = new String[0];
		chapterResults = new String[0];
		allDocs = new ScoreDoc[0];
	}
	
	public String getDocumentAtIndex(int i) throws Exception{
		FSDirectory dir = FSDirectory.open(new File(index));
		IndexSearcher searcher = new IndexSearcher(dir, true);
		TopScoreDocCollector collector = TopScoreDocCollector.create(10000, true);
	    searcher.search(currentQuery,collector);
	    Document doc = searcher.doc(allDocs[i].doc);
		return (doc.get("verse"));
	}
	
	public String[] getTstmtsResults() {
		return tstmtsResults;
	}

	public String[] getBookResults() {
		return bookResults;
	}

	public String[] getChapterResults() {
		return chapterResults;
	}
	
	public void filterResultsRText(String RText) throws Exception{
		search((currentQuery + " title:" + RText), true, false, false, true);
	}
	
	public void filterResultsBook(int bookIndex) throws Exception{
		boolean done = false;
		int currentLetter = bookResults[bookIndex].length()-1;
		String bookFixedName = bookResults[bookIndex];
		System.out.println("Starting loop...");
		while(!done){
			if(bookFixedName.charAt(currentLetter)=='('){
				bookFixedName = bookFixedName.substring(0,currentLetter);
				done=true;
			}	
			else
				System.out.println("Decrementing : " + currentLetter);
				currentLetter--;
		}
		
		String filteredQuery = (currentQuery + " AND bktlong:\"" + bookFixedName + "\"");
		System.out.println("Filtered search = " + filteredQuery);
		search(filteredQuery,false, false, true, true);
	}
	
	public void filterResultsVerse(String Verse) throws Exception{
		search((currentQuery + " verse:" + Verse), false, false, true, true);
	}
	
	public void search(String generalQuery, boolean updateTstmt, boolean updateBook, boolean updateChp, boolean filteredQuery) throws Exception{
		
		
		
		ArrayList<String> bookTitlesFound = new ArrayList<String>(), 
						  tstTitlesFound = new ArrayList<String>(),
						  versesFound = new ArrayList<String>();
		ArrayList<Integer> bookTitleOccurances = new ArrayList<Integer>(),
						   tstTitlesOccurances = new ArrayList<Integer>();

		 // this is the index dir
		FSDirectory dir = FSDirectory.open(new File(index));

		IndexSearcher searcher = new IndexSearcher(dir, true);

	    Query q = new QueryParser(Version.LUCENE_CURRENT, "verse", new StandardAnalyzer(Version.LUCENE_CURRENT)).parse(generalQuery);
	    if(!filteredQuery)currentQuery = q;
	    
	    TopScoreDocCollector collector = TopScoreDocCollector.create(10000, true);
	    searcher.search(q,collector);
    	ScoreDoc[] hits = collector.topDocs().scoreDocs;
    	if(hits.length == 0){
    		setNoResults();
    		return;
    	}
    	
    	allDocs = hits;

	    int newtesthits=0;
	    
	    
	    for (int i=0; i<hits.length; i++) {
	    	Document doc = searcher.doc(hits[i].doc);
	    	if(doc.get("title").equals("The New Testament"))
	    		newtesthits++;
	    	
	    	//Save found tstmts and the amount of matches in each
	    	int y = tstTitlesFound.indexOf(doc.get("title"));
	    	if(y>-1){
	    		tstTitlesOccurances.set(y,tstTitlesOccurances.get(y)+1);
	    	}else{
	    		tstTitlesFound.add(doc.get("title"));
	    		tstTitlesOccurances.add(new Integer(1));
	    	}
	    	
	    	//Save found books and the amount of matches in each
	    	int x = bookTitlesFound.indexOf(doc.get("bktlong"));
	    	if(x>-1){
	    		bookTitleOccurances.set(x,bookTitleOccurances.get(x)+1);
	    	}else{
	    		bookTitlesFound.add(doc.get("bktlong"));
	    		bookTitleOccurances.add(new Integer(1));
	    	}
	    	
	    	versesFound.add(doc.get("verse"));
	    	
	    }
	    
	    String[] tstmtsResultsTmp = new String[tstTitlesFound.size()];
	    for(int k=0;k<tstTitlesFound.size();k++){
	    	tstmtsResultsTmp[k] =  tstTitlesFound.get(k) + " (" + tstTitlesOccurances.get(k) + ")";
	    }
	    
	    String[] bookResultsTmp = new String[bookTitlesFound.size()];
	    for(int j=0;j<bookTitlesFound.size();j++){
	    	bookResultsTmp[j] =  bookTitlesFound.get(j) + " (" + bookTitleOccurances.get(j) + ")";
	    }
	    
	    String[] chpTmp = new String[versesFound.size()];
	    for(int l=0;l<versesFound.size();l++){
	    	chpTmp[l] = versesFound.get(l);
	    }
	    
	    if(updateTstmt)tstmtsResults = tstmtsResultsTmp;
	    if(updateBook)bookResults = bookResultsTmp;
	    if(updateChp)chapterResults = chpTmp;

		this.setChanged();
		this.notifyObservers();
	}

	private void setNoResults(){
		tstmtsResults = new String[]{"All (0)"};
		bookResults = new String[]{"All (0)"};
		chapterResults = new String[]{""};
		this.setChanged();
		this.notifyObservers();
	}
	
	public String getIndexSrcFilesLoc(){
		return xmlFilePath;
	}
	
	public void setIndexSrcFilesLoc(String newLoc){
		xmlFilePath = newLoc;
	}

	public void setIndexDest(String indexDest) {
		index = indexDest;
	}
	
	public String getIndexDest(){
		return index;
	}
	
	public boolean startIndexing(){
		try{
			File dir = new File(xmlFilePath); 
		File[] children = dir.listFiles();
		Indexer i = new Indexer();
		i.init(children, index);
		return true;
		} catch (Exception e){
			System.err.println("Some kind of file error " + e);
			return false;
		}
	}
}
